// CSE571 - signal-handler.cpp
// Authors: Guangle Fan
// This class handles sending messages after SIGINT is triggered

#include "sig-timer-handler.h"
#include "io-manager.h"
#include "async-io-svc-handler.h"
#include "globals.h"

const int INITIAL_DELAY = 1;
const int INTERVAL = 1;

PlayerSigTimerHandler::PlayerSigTimerHandler (ACE_Reactor *reactor) : triggered (false) {
  ACE_Time_Value initialDelay (INITIAL_DELAY);
  ACE_Time_Value interval (INTERVAL);
  reactor->schedule_timer (this, 0, initialDelay, interval);
}

int PlayerSigTimerHandler::handle_timeout (const ACE_Time_Value &, const void*) {
  if (SigHandler::sigint_fired() && !triggered) {
    //send shut down msg to all games
    triggered = true;
  
    GameManager * manager = GameManager::instance();
    PlayerGame* gpt;
    for(unsigned int i = 0; i < manager->num_games(); ++i) {
      if (!gpt->failed) {
	gpt = manager->get_game(i);
      	IOManager::instance()->enqueue_resume(&(gpt->handler));
        if (!gpt->handler.counterpart_quit) gpt->send_msg(CLIENT_QUIT_MSG);
      }
    }
    if (manager->num_games() == 0) {
      IOManager::instance()->enqueue((AsyncIOSvcHandler*) 0, 0);
    }
  }
  return 0;
}

DealerSigTimerHandler::DealerSigTimerHandler (ACE_Reactor *reactor) : triggered (false){
  ACE_Time_Value initialDelay (INITIAL_DELAY);
  ACE_Time_Value interval (INTERVAL);
  reactor->schedule_timer (this, 0, initialDelay, interval);
}

int DealerSigTimerHandler::handle_timeout (const ACE_Time_Value &, const void*) {
  if (SigHandler::sigint_fired() && !triggered) {
    Dealer * dealer = Dealer::instance();
    map<string, Game *>::iterator giter;

    dealer->resume();
    map<string, Player *>::iterator piter;
    if (DEBUG) {
      std::cout << "# Players when quitting: " << dealer->players.size()
		<< std::endl;
    }
    if (dealer->players.size() != 0) {
      for(piter = dealer->players.begin(); piter != dealer->players.end();
	  ++piter) {
        if (DEBUG) std::cout << "Enqueuing termination ACT." << std::endl;
        if (!piter->second->handler.counterpart_quit) {
	  piter->second->send_msg(SERVER_QUIT_MSG);
	}
      }
    } else {
      IOManager::instance()->enqueue((AsyncIOSvcHandler*) 0, 0);
    }
    triggered = true;
  }
  return 0;
}
